﻿using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Reflection;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Yuebon.Commons.Helpers;
using Yuebon.Commons.Log;
using Yuebon.Commons.Models;
using Yuebon.Commons.Options;
using Yuebon.WebApi.Common;
using Yuebon.WebApi.Models;

namespace Yuebon.WebApi
{
    /// <summary>
    /// Token令牌提供类
    /// </summary>
    public class TokenProvider
    {
        private readonly JwtOption _jwtModel;
        /// <summary>
        /// 构造函数
        /// </summary>
        public TokenProvider() { }
        /// <summary>
        /// 构造函数，初花jwtmodel
        /// </summary>
        /// <param name="jwtModel"></param>
        public TokenProvider(JwtOption jwtModel)
        {
            _jwtModel = jwtModel;
        }
        /// <summary>
        /// 直接通过appid和加密字符串获取访问令牌接口
        /// </summary>
        /// <param name="grant_type">获取access_token填写client_credential</param>
        /// <param name="appid">用户唯一凭证</param>
        /// <param name="secret">用户唯一凭证密钥，即appsecret</param>
        /// <returns></returns>
        public async  Task<TokenResult> GenerateToken(string grant_type, string appid, string secret)
        {
            var now = DateTime.UtcNow;

            ClaimsIdentity claims = new ClaimsIdentity(grant_type);
            var symmetricKeyAsBase64 = secret;
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            var expires = now.Add(TimeSpan.FromMinutes(_jwtModel.Expiration));
            var signingCredentials=new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            

            string jwtToken = new JwtSecurityTokenHandler().CreateEncodedJwt(_jwtModel.Issuer,appid, claims, now,expires,null, signingCredentials);

            TokenResult result = new TokenResult();
            result.AccessToken = jwtToken;
            result.ExpiresIn = (int)TimeSpan.FromMinutes(_jwtModel.Expiration).TotalMinutes;
            return  result;
        }
        /// <summary>
        /// 检查用户的Token有效性
        /// </summary>
        /// <param name="token">token令牌</param>
        /// <returns></returns>
        public CommonResult ValidateToken(string token)
        {
            //返回的结果对象
            CommonResult result = new CommonResult();

            if (!string.IsNullOrEmpty(token))
            {
                try
                {
                    JwtSecurityToken jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(token);
                    if (jwtToken!=null)
                    {
                        #region 检查令牌对象内容
                        
                        if (DateTime.UtcNow > jwtToken.ValidTo)
                        {
                            result.ErrMsg = ErrCode.err40005;
                            result.ErrCode = "40005";
                        }
                        else
                        {
                            result.ErrMsg = ErrCode.err0;
                            result.ErrCode = ErrCode.successCode;
                        }
                        #endregion
                    }
                    else
                    {
                        result.ErrMsg = ErrCode.err40004;
                        result.ErrCode = "40004";
                    }
                }
                catch (Exception ex)
                {
                    var type = MethodBase.GetCurrentMethod().DeclaringType;
                    Log4NetHelper.WriteError(type,ex);
                    throw new MyApiException(ErrCode.err40004, "40004");
                }
            }
            else
            {
                result.ErrMsg = ErrCode.err40004;
                result.ErrCode = "40004";
            }
            return result;
        }
    }
}
